/**
 * Created on 28.09.15.
 */
"use strict";
var isDbg = false;
var dbg = function (data) {
    if (!isDbg) return false;
    console.log(data);
};
var onloadCb = $.noop;
var isLoadInit = false;

var CaptchaManager = function () {
    dbg('construct');
    var self = this;

    self._type = window.CAPTCHA_MANAGER_INFO.type;
    self._pubKey = window.CAPTCHA_MANAGER_INFO.publicKey;
    self._injectJs = window.CAPTCHA_MANAGER_INFO.injectJs;

    self._inputFieldElement = null;
    self._reloadElement = null;
    self._gRecaptcha = null;
    self._oCaptcha = null;
    self._phpCaptcha = null;

    self._id = 'captcha_' + (+(new Date()) + Math.ceil(Math.random() * 1000));
};

CaptchaManager.prototype.TYPE = {
    GOOGLE: 'google',
    PHP: 'php',
    NODE: 'node'
};

//Перерисовывает капчу
CaptchaManager.prototype.reload = function (cb) {
    dbg('reload');
    var self = this;
    cb = cb || $.noop;
    switch (self._type) {
        case self.TYPE.GOOGLE:
            grecaptcha.reset(self._gRecaptcha);
            cb();
            break;
        case self.TYPE.NODE:
            self._oCaptcha.reload(function (data) {
                $('#' + self._id + ' pre').html(data.drawData);
                cb();
            });
            break;
        case  self.TYPE.PHP:
            $.get('/ajax/?controller=capcha&v=' + Math.random(), function(data){
                self._phpCaptcha.attr('src', data.uri);
                self._phpCaptcha.attr('data-captcha-id', data.id);
                cb();
            });
            break;
    }
};

// Инициализирует капчу
CaptchaManager.prototype.init = function (cb) {
    dbg('init');
    var self = this;
    cb = cb || $.noop;

    if (self._injectJs) {
        var script = document.createElement('script');
        script.src = self._injectJs;
        document.body.appendChild(script);
    }

    switch (self._type) {
        case self.TYPE.GOOGLE:
            var checkGrecaptcha = function () {
                if (window.grecaptcha) {
                    self._gRecaptcha = grecaptcha.render(self._id, {
                        sitekey: self._pubKey
                    });
                    cb();
                } else {
                    setTimeout(checkGrecaptcha, 100);
                }
            };
            checkGrecaptcha();
            break;
        case self.TYPE.NODE:
            var checkOCaptcha = function () {
                if (window.OCaptcha) {
                    self._oCaptcha = new OCaptcha();
                    $('<pre>').css({
                        'font-size': '3px',
                        'line-height': '2px',
                        'height': '65px',
                        '-webkit-touch-callout': 'none',
                        '-webkit-user-select': 'none',
                        '-khtml-user-select': 'none',
                        '-moz-user-select': 'none',
                        '-ms-user-select': 'none',
                        '-o-user-select': 'none',
                        'user-select': 'none',
                        'cursor': 'default'
                    }).appendTo($('#' + self._id));

                    self._oCaptcha.reload(function (data) {
                        $('#' + self._id + ' pre').html(data.drawData);
                        cb();
                    });
                } else {
                    setTimeout(checkOCaptcha, 100);
                }
            };
            checkOCaptcha();
            break;
        case self.TYPE.PHP:
            $.get('/ajax/?controller=capcha&v=' + Math.random(), function (data) {
                self._phpCaptcha = $('<img>', {
                    src: data.uri,
                    'data-captcha-id': data.id
                });
                self._phpCaptcha.appendTo($('#' + self._id));
            });
            break;
    }
};

//Проверяет пользовательский ввод, и если он верен, то возвращает через каллбек токен проверки(либо введенный код для php капчи)
CaptchaManager.prototype.check = function (cb) {
    var self = this;

    switch (self._type) {
        case self.TYPE.GOOGLE:
            var res = grecaptcha.getResponse(self._gRecaptcha);
            cb(res ? res : false);
            break;
        case self.TYPE.NODE:
            self._oCaptcha.check(self._inputFieldElement.val(), function (data) {
                if (!data.isSuccess) {
                    cb(false);
                } else {
                    cb(data.checkToken);
                }
            });
            break;
        case self.TYPE.PHP:
            var code = self._inputFieldElement.val();
            if(!code){
                cb(false);
            }else{
                cb(code + ':' + self._phpCaptcha.attr('data-captcha-id'));
            }
            break;
    }
};

CaptchaManager.prototype.setInputField = function (element) {
    dbg('setInputField');
    dbg(element);
    var self = this;
    if (typeof(element) === 'string') {
        element = $('#' + element)[0];
    }
    element = $(element);
    self._inputFieldElement = element;
    if (self._type === self.TYPE.GOOGLE) {
        element.hide();
    }
};

CaptchaManager.prototype.setReloadElement = function (element) {
    dbg('setReloadElement');
    dbg(element);
    var self = this;
    if (typeof(element) === 'string') {
        element = $('#' + element)[0];
    }
    element = $(element);
    self._reloadElement = element;
    self._reloadElement.on('click', function () {
        self.reload();
        return false;
    });
    if (self._type === self.TYPE.GOOGLE) {
        element.hide();
    }
};

CaptchaManager.prototype.getParams = function () {
    var self = this;
    return {
        type: self._type,
        isUseReloadElement: (self._type == self.TYPE.NODE || self._type == self.TYPE.PHP),
        isUseInputField: (self._type == self.TYPE.NODE || self._type == self.TYPE.PHP),
    };
};

CaptchaManager.onload = function (cb) {
    cb = cb || $.noop;
    if (isLoadInit) {
        cb();
    }
    onloadCb = cb;
};

$(function () {
    $('.captcha-manager-wrapper').each(function () {
        var $this = $(this);
        var cm = new CaptchaManager();
        $('<div>', {id: cm._id}).appendTo($this);
        cm.init();
        $this.data('captchaManager', cm);
        isLoadInit = true;
        onloadCb();
        dbg('onloadCb');
    });
});